package com.example.demo.controller.admin;

import com.example.demo.Util.Result;
import com.example.demo.Util.ResultUtil;
import com.example.demo.Util.redisUtil.RedisService;
import com.example.demo.mapper.CourseMap;
import com.example.demo.mapper.LabMap;
import com.example.demo.mapper.StudentMap;
import com.example.demo.mapper.TeacherMap;
import com.example.demo.po.dto.CourseParam;
import com.example.demo.po.dto.LabUsageParam;
import com.example.demo.po.dto.StudentParam;
import com.example.demo.po.dto.TeacherParam;
import com.example.demo.service.CourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/course")
public class CourseController {

    @Autowired
    CourseMap courseMap;

    @Autowired
    LabMap labMap;

    @Autowired
    TeacherMap teacherMap;

    @Autowired
    StudentMap studentMap;


    @Autowired
    CourseService courseService;


    @Autowired
    RedisService redisService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @GetMapping("/get")
    Result getCourse(){

        return ResultUtil.success(courseMap.GetCourse()) ;
    }

    @PostMapping("/save")
    Result saveResult(@RequestBody CourseParam courseParam){

       Result result =   courseService.SaveCourse(courseParam);
        return result;
    }
     @GetMapping("/delete/{id}")
    Result deleteCourse(@PathVariable("id") int id){

        courseMap.DeleteCourse(id);

        return ResultUtil.success("删除成功");
     }

     @PostMapping("/update")
    Result updateCourse(@RequestBody CourseParam courseParam) throws ParseException {
         System.out.println(courseParam);
         courseService.UpdateCourse(courseParam);
        return ResultUtil.success("更新成功");

     }

    @GetMapping("/search")
    Result SearchCourse(@RequestParam("name") String name,@RequestParam("teacherName") String teacherName){

        if(StringUtils.isEmpty(name)&&StringUtils.isEmpty(teacherName)){
            return ResultUtil.success(      courseMap.GetCourse() );

        }

        if(!StringUtils.isEmpty(name)&& !StringUtils.isEmpty(teacherName)){
            return   ResultUtil.success( courseMap.GetCourseByAll("%"+name+"%","%"+teacherName+"%")) ;
        }else if(!StringUtils.isEmpty(name)){
            return ResultUtil.success( courseMap.GetCourseByName("%"+name+"%")) ;
        }else {
            return ResultUtil.success( courseMap.GetCourseByTeacherName("%"+teacherName+"%")) ;
        }


    }

    @GetMapping("/getLabUsage")
    Result GetLabUsage(){
        Date dNow = new Date();   //当前时间

        Calendar calendar = Calendar.getInstance(); //得到日历
        calendar.setTime(dNow);//把当前时间赋给日历
        calendar.add(Calendar.DAY_OF_MONTH, -1);  //设置为前一天
        Date dBefore  = calendar.getTime();   //得到前一天的时间
        dBefore.setMinutes(0);
        dBefore.setSeconds(0);
        dBefore.setHours(0);
        calendar.add(Calendar.DAY_OF_MONTH, -1);  //设置为前一天
        Date dBeBefore = calendar.getTime();   //得到前一天的时间
        dBeBefore.setMinutes(0);
        dBeBefore.setSeconds(0);
        dBeBefore.setHours(0);



        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); //设置时间格式

        String bebeTime = sdf.format(dBeBefore);    //格式化前二天
        String beTime = sdf.format(dBefore);    //格式化前一天
        String nowTime = sdf.format(dNow); //格式化当前时间
        System.out.println(bebeTime);
        System.out.println(beTime);
        System.out.println(nowTime);
        int count = labMap.CountLab();
        Integer judgeInt = courseMap.GetCountByTime(nowTime);
        int coutNow = judgeInt==null?0:judgeInt;
        judgeInt = courseMap.GetCountByTime(beTime);
        int countBefore = judgeInt==null?0:judgeInt;
        judgeInt = courseMap.GetCountByTime(bebeTime);
        int countbebeore = judgeInt==null?0:judgeInt;

        List<LabUsageParam> list = new ArrayList<>();
        list.add(new LabUsageParam(bebeTime,countbebeore,count-countbebeore));
        list.add(new LabUsageParam(beTime,countBefore,count-countBefore));
       list.add(new LabUsageParam(nowTime,coutNow,count-coutNow));


        return ResultUtil.success(list);

    }


    @GetMapping("/getMyCourse")
    Result GetMyCourse(@RequestParam("userid") int userid){

     TeacherParam teacherid = teacherMap.GetTeacherByUserId(userid);


        return ResultUtil.success(courseMap.GetMyCourse(teacherid.getId()));

    }

    //searchMycourse
    @GetMapping("/searchMycourse")
    Result SearchMyCourse(@RequestParam("name") String name,@RequestParam(value = "teacherid",defaultValue = "-1") int teacherid){

        if(StringUtils.isEmpty(name)||teacherid==-1){
          return ResultUtil.success(  courseMap.GetMyCourse(teacherid) );
        }


        return ResultUtil.success(  courseMap.SearchMyCourse(teacherid,"%"+name+"%") );

    }


    //涉及并发处理

    //todo 按钮置灰  课程加状态

    @GetMapping("/chooseCourse")
    Result SearchMyCourse(@RequestParam("courseid") int courseid,@RequestParam(value = "stuid",defaultValue = "-1") int stuid){

        if(stuid==-1){
            return ResultUtil.success("参数无效" );
        }
        String uuid =  java.util.UUID.randomUUID().toString();


       Result res =  new RedisLockTemplate<Boolean>() {
            @Override
            public Result ActionInLock() {

                //判断
                StudentParam stu = studentMap.GetStudentByUserId(stuid);
                Integer count =  courseMap.GetChooseCourse(stu.getId(),courseid);
                if(count>=1){
                    return ResultUtil.fail(  "已选课" );
                }


                //减少课程人数
                if(courseMap.CourseNumDecr(courseid) == 0 ){
                    return ResultUtil.fail("课程人数已满");
                }

                //增加自己的课程
                courseMap.SaveChooseCourse(stu.getId(),courseid);

                return ResultUtil.success("添加课程成功");
            }
        }.executeSafely( redisService, uuid, courseid);


        //redis tryLock

//        StudentParam stu = studentMap.GetStudentByUserId(stuid);
//
//       Integer count =  courseMap.GetChooseCourse(stu.getId(),courseid);
//        if(count>=1){
//            return ResultUtil.fail(  "已选课" );
//        }
//        //如果课程人数已满，提示已满
//
//
//        courseMap.SaveChooseCourse(stu.getId(),courseid);


        return res;

    }








    public static abstract class  RedisLockTemplate<T> {


        Result executeSafely(RedisService redisService,String requsetid,int courseid){
            boolean res =   redisService.TryGetLock(requsetid,courseid);
             if(!res) return ResultUtil.fail("稍后重试");

            try {
                return ActionInLock();
            }finally {
               redisService.UnLock(requsetid,courseid);
            }

        }

        public abstract Result ActionInLock();



    }


}
